package com.kepler.social.domain.user.security;


import com.kepler.social.common.constants.Enums;
import com.kepler.social.common.constants.TipsConst;
import com.kepler.social.common.exception.ServiceException;
import com.kepler.social.common.exception.SystemException;
import com.kepler.social.domain.user.account.consts.BusinessSeqEnum;
import com.kepler.social.generic.SeqHelper;
import com.kepler.social.generic.SpringContextHelper;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Slf4j
public class UserSecurityDomainService {

    @Resource
    private SeqHelper seqHelper;
    @Resource
    private UserSecurityRepository userSecurityRepository;

    /**
     * 用户重置密码，一般
     *
     * @param email
     * @param encodePassword
     */
    public void resetPasswordByEmail(String email, String encodePassword) {
        UserSecurityAggregate aggregate = userSecurityRepository.findByEmail(email);
        aggregate.checkEmailInUse();
        userSecurityRepository.updatePassword(aggregate, encodePassword);
    }

    /**
     * 这个是重置密码，含有业务信息，如果方法未作特别说明，表示注册完成之后
     *
     * @param countryCallingCode
     * @param mobilePhoneNumber
     * @param encodePassword
     */
    public void resetPasswordByPhone(Integer countryCallingCode, Long mobilePhoneNumber, String encodePassword) {
        UserSecurityAggregate aggregate = userSecurityRepository.findByMobilePhone(countryCallingCode, mobilePhoneNumber);
        aggregate.checkMobilePhoneInUse();
        userSecurityRepository.updatePassword(aggregate, encodePassword);
    }

    /**
     * 预创建
     *
     * @param countryCallingCode
     * @param mobilePhoneNumber
     * @param encryptedPassword
     * @return
     */
    public UserSecurityAggregate preCreateOfMobilePhone(Integer countryCallingCode, Long mobilePhoneNumber,
                                                        String encryptedPassword) {
        UserSecurityAggregate aggregate = userSecurityRepository.findByMobilePhone(countryCallingCode, mobilePhoneNumber);
        aggregate.checkMobilePhoneNotInUse();
        if (!aggregate.isMobilePhoneExist()) {
            aggregate = SpringContextHelper.getBean(UserSecurityDomainService.class)
                    .createOfMobilePhoneToBeVerified(countryCallingCode, mobilePhoneNumber, encryptedPassword);
        } else if (aggregate.isMobilePhoneToBeVerify()) {
            // 走到这里一定是待验证，子所以写这个判断主要是起标识的作用
            userSecurityRepository.updatePassword(aggregate, encryptedPassword);
        } else {
            // 这里的else不会进来，仅仅是为了完善if else的语法
            throw new SystemException(TipsConst.system_error_shouldn_not_happen);
        }
        return aggregate;
    }

    @Transactional(rollbackFor = Exception.class)
    public UserSecurityAggregate createOfMobilePhoneToBeVerified(Integer countryCallingCode, Long mobilePhoneNumber,
                                                                 String encryptedPassword) {
        Long userId = seqHelper.getSeqId(BusinessSeqEnum.USER.getBusinessName());
        Long phoneId = seqHelper.getSeqId(BusinessSeqEnum.USER_MOBILE_PHONE.getBusinessName());
        log.info("userId {}  phoneId {}", userId, phoneId);
        UserSecurityAggregate aggregate = UserSecurityFactory.toBeVerifiedOfMobilePhone(countryCallingCode,
                mobilePhoneNumber, phoneId, userId, encryptedPassword);
        userSecurityRepository.create(aggregate);
        return aggregate;
    }

    public void finishCreateOfMobile(UserSecurityAggregate aggregate) {
        aggregate.checkMobilePhoneNotInUse();
        userSecurityRepository.updateMobileState(aggregate, Enums.UserMobilePhoneStateEnum.USED);
    }

    /**
     * 预创建
     *
     * @param email
     * @param encryptedPassword
     */
    public UserSecurityAggregate preCreateOfEmail(String email, String encryptedPassword) {
        UserSecurityAggregate aggregate = userSecurityRepository.findByEmail(email);
        if (!aggregate.isEmailExist()) {
            aggregate = SpringContextHelper.getBean(UserSecurityDomainService.class).createOfEmailToBeVerified(email,
                    encryptedPassword);
        } else if (aggregate.isEmailToBeVerify()) {
            userSecurityRepository.updatePassword(aggregate, encryptedPassword);
        } else {
            throw new ServiceException(TipsConst.email_used);
        }
        return aggregate;
    }

    @Transactional(rollbackFor = Exception.class)
    public UserSecurityAggregate createOfEmailToBeVerified(String email, String encryptedPassword) {
        Long userId = seqHelper.getSeqId(BusinessSeqEnum.USER.getBusinessName());
        UserSecurityAggregate aggregate = UserSecurityFactory.toBeVerifiedOfEmail(email, userId, encryptedPassword);
        userSecurityRepository.create(aggregate);
        return aggregate;
    }

    public void finishCreateOfEmail(UserSecurityAggregate aggregate) {
        userSecurityRepository.updateEmailState(aggregate, Enums.UserEmailStateEnum.USED);
    }


}
